package xin.nick.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import xin.nick.common.util.MyAssert;
import xin.nick.converter.AuthorityConverter;
import xin.nick.converter.RoleConverter;
import xin.nick.domain.dto.RoleSetAuthorityListDTO;
import xin.nick.domain.vo.AuthorityVO;
import xin.nick.domain.vo.RoleSetAuthorityListVO;
import xin.nick.domain.vo.RoleVO;
import xin.nick.entity.Authority;
import xin.nick.entity.Role;
import xin.nick.entity.RoleAuthority;
import xin.nick.manager.AuthorityManager;
import xin.nick.mapper.AuthorityMapper;
import xin.nick.mapper.RoleAuthorityMapper;
import xin.nick.mapper.RoleMapper;
import xin.nick.service.IRoleAuthorityService;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色权限关联 服务实现类
 * </p>
 *
 * @author Nick
 * @since 2022-08-10
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class RoleAuthorityServiceImpl extends ServiceImpl<RoleAuthorityMapper, RoleAuthority> implements IRoleAuthorityService {


    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private AuthorityMapper authorityMapper;

    @Autowired
    private AuthorityManager authorityManager;

    /**
     * 根据角色id获取权限列表
     * @param roleId
     * @return
     */
    @Override
    public List<AuthorityVO> getAuthorityListByRoleId(Long roleId) {

        List<AuthorityVO> resultList = new ArrayList<>();

        checkRole(roleId);

        // 获取对应的角色权限关联信息
        List<RoleAuthority> roleAuthorityList = list(Wrappers.<RoleAuthority>lambdaQuery().eq(RoleAuthority::getRoleId, roleId));

        if (CollectionUtils.isEmpty(roleAuthorityList)) {
            return resultList;
        }
        // 获取到所有的权限id 列表,然后去权限表中获取所有权限信息
        List<Long> authorityIdList = roleAuthorityList.stream().map(RoleAuthority::getAuthorityId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(authorityIdList)) {
            return resultList;
        }
        List<Authority> authorityList = authorityMapper.selectList(Wrappers.<Authority>lambdaQuery()
                                                                    .in(Authority::getAuthorityId, authorityIdList));
        resultList = AuthorityConverter.INSTANCE.toVoList(authorityList);

        return resultList;
    }

    /**
     * 设置角色的权限列表
     * @param roleSetAuthorityListDTO
     * @return
     */
    @Override
    public RoleSetAuthorityListVO setRoleAuthorityList(RoleSetAuthorityListDTO roleSetAuthorityListDTO) {

        Long roleId = roleSetAuthorityListDTO.getRoleId();
        List<Long> authorityIdList = roleSetAuthorityListDTO.getAuthorityIdList();

        checkRole(roleId);

        RoleSetAuthorityListVO roleSetAuthorityListVO = buildRoleSetAuthorityListVO(roleSetAuthorityListDTO);

        // 简单粗暴的方式
        // 删掉以前的记录
        remove(Wrappers.<RoleAuthority>lambdaQuery().eq(RoleAuthority::getRoleId, roleId));

        // 过滤掉不存在的权限
        authorityIdList = authorityManager.filterExistingIdList(authorityIdList);

        // 添加新记录
        if (CollectionUtils.isEmpty(authorityIdList)) {
            return roleSetAuthorityListVO;
        }

        List<RoleAuthority> insertRoleAuthorityList = new ArrayList<>();
        for (Long authorityId : authorityIdList) {
            RoleAuthority roleAuthority = new RoleAuthority();

            roleAuthority.setRoleId(roleId);
            roleAuthority.setAuthorityId(authorityId);
            insertRoleAuthorityList.add(roleAuthority);
        }
        saveBatch(insertRoleAuthorityList);

        return roleSetAuthorityListVO;
    }


    /**
     * 组装 角色设置权限列表西信息
     * @param roleSetAuthorityListDTO
     * @return
     */
    private RoleSetAuthorityListVO buildRoleSetAuthorityListVO(RoleSetAuthorityListDTO roleSetAuthorityListDTO) {
        RoleSetAuthorityListVO result = new RoleSetAuthorityListVO();
        Long roleId = roleSetAuthorityListDTO.getRoleId();
        List<Long> authorityIdList = roleSetAuthorityListDTO.getAuthorityIdList();

        // 角色信息
        Role role = roleMapper.selectById(roleId);
        RoleVO roleVO = RoleConverter.INSTANCE.roleToRoleVo(role);
        result.setRole(roleVO);

        // 权限信息
        if (CollectionUtils.isEmpty(authorityIdList)) {
            return result;
        }
        List<Authority> authorityList = authorityMapper.selectList(Wrappers.<Authority>lambdaQuery()
                .in(Authority::getAuthorityId, authorityIdList));
        List<AuthorityVO> authorityVoList = AuthorityConverter.INSTANCE.toVoList(authorityList);
        result.setAuthorityList(authorityVoList);

        return result;
    }

    /**
     * 检查角色信息
     */
    private void checkRole(Long roleId) {
        MyAssert.notNull(roleId, "[roleId] 不可为空");
        Role role = roleMapper.selectById(roleId);
        MyAssert.notNull(role, "角色信息不存在");
    }

}
